package com.course.util;

import java.util.*;
import java.util.function.Supplier;

/**
 * 给定table以及某列有哪些列值，生成包含了所有这些列值的数据(非笛卡尔积形式，仅仅是会在表中出现)
 * Created by ialis on 2018-11-19
 */
public class DataGenerator {

    public static class SequenceSupplier implements Supplier<Integer> {

        private int val;

        public SequenceSupplier(int init) {
            this.val = init;
        }

        @Override
        public Integer get() {
            return val++;
        }
    }


    private String table;

    private StringBuilder sql = new StringBuilder();

    private StringBuilder result = null;

    private Map<String, Supplier> srcs = new LinkedHashMap<>();

    private Map<String, List> rows = new HashMap<>();

    public DataGenerator(String tablename) {
        this.table = tablename;
        sql.append("INSERT INTO ")
                .append(tablename)
                .append("(");

    }

    public <T> DataGenerator with(String column, List<T> values) {
        sql.append(column).append(",");
        srcs.put(column, () -> values.get(((int) Math.floor(Math.random() * values.size()))));
        return this;
    }

    public <T> DataGenerator with(String column, Supplier<T> supplier) {
        sql.append(column).append(",");
        srcs.put(column, supplier);
        return this;
    }

    public DataGenerator with(String column, List<String> prefixs, List<String> postfixs) {
        ArrayList<String> values = new ArrayList<>();
        for (String prefix : prefixs) {
            for (String postfix : postfixs) {
                values.add(prefix + postfix);
            }
        }
        return with(column, values);
    }

    public DataGenerator with(String column, Integer first, Integer last) {
        ArrayList<Integer> values = new ArrayList<>();
        for (Integer i = first; i <= last; i++) {
            values.add(i);
        }
        return with(column, values);
    }

    public DataGenerator generate(int row) {
        if (result != null) {
            return this;
        }
        result = new StringBuilder();
        if (sql.charAt(sql.length() - 1) == ',') {
            sql.deleteCharAt(sql.length() - 1);
        }
        sql.append(") VALUES(");
        String pre = sql.toString();
        for (int i = 0; i < row; i++) {
            sql = new StringBuilder(pre);
            srcs.forEach((column, value) -> {
                Object v = value.get();
                if (v instanceof Number) {
                    sql.append(v);
                } else if (v instanceof CharSequence) {
                    sql.append("'").append(v).append("'");
                } else {
                    throw new RuntimeException("not support type: " + v.getClass());
                }
                sql.append(",");
                List list = rows.computeIfAbsent(column, k -> new ArrayList());
                list.add(v);
            });
            if (sql.charAt(sql.length() - 1) == ',') {
                sql.deleteCharAt(sql.length() - 1);
            }
            sql.append(");\n");
            result.append(sql);
        }
        return this;
    }

    public String getSql() {
        return result.toString();
    }

    public <T> List<T> getColumn(String column) {
        return rows.get(column);
    }

    public static void main(String[] args) {
        List<String> courseNames = Arrays.asList("高等数学A", "高等数学B", "高等数学C",
                "高等数学D", "高等数学E", "高等数学F", "高等数学G");
        DataGenerator generator = new DataGenerator("course")
                .with("name", courseNames)
                .with("state", Arrays.asList(1, 2))
                .generate(2);
        System.out.println(generator.getSql());
        System.out.println(generator.getColumn("name"));
        System.out.println(generator.getColumn("state"));
    }

}
